package jp.androidgroup.chiba.androidresearch.ui;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import jp.androidgroup.chiba.androidresearch.Common;
import jp.androidgroup.chiba.androidresearch.R;
import jp.androidgroup.chiba.androidresearch.data.Base;
import jp.androidgroup.chiba.androidresearch.data.Place;
import jp.androidgroup.chiba.androidresearch.data.Time;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * 日時・場所選択ダイアログを表示するクラス
 * 
 * @author noxi
 *
 */
public class CounterInfoDialog {
	
	/**
	 * 日付・時間選択ダイアログのボタンをクリックした際に呼ばれるインターフェース
	 * 
	 * @author noxi
	 *
	 */
	public interface OnClickListener {
		/**
		 * OKボタンクリック時
		 * 
		 * @param date 日付
		 * @param time 時間
		 * @param place 場所
		 * @param memo メモ
		 */
		public void onPositiveClick(String date, String time, String place, String memo);
		
		/**
		 * キャンセルボタンクリック時
		 */
		public void onNegativeClick();
	}
	
	public static final String PREF_PLACE_ID = "placeid";
	
	
	protected static final SimpleDateFormat sDateFormat;
	
	static {
		sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	}
	
	/**
	 * Context情報
	 */
	protected Context mContext;
	/**
	 * ボタンのクリックリスナー
	 */
	protected OnClickListener mListener;
	/**
	 * Default SharedPreferences
	 */
	protected SharedPreferences mPref;
	
	/**
	 * 日付
	 */
	protected Date mDate;
	/**
	 * 時間
	 */
	protected String mTime;
	/**
	 * 場所
	 */
	protected String mPlace;
	/**
	 * メモ
	 */
	protected String mMemo;
	
	/**
	 * ダイアログのキャンセル可否
	 */
	protected boolean mCancel = false;
	
	
	public CounterInfoDialog(Context context, OnClickListener listener) {
		mContext = context;
		mListener = listener;
		
		mPref = PreferenceManager.getDefaultSharedPreferences(context);
		mMemo = "";
		
		// 前回指定した場所を取得
		mPlace = mPref.getString(PREF_PLACE_ID, "");
		
		// 日時初期化
		mDate = new Date();
		
		final int timeTerm = context.getResources().getInteger(R.integer.v_time_term);
		int mm = Integer.parseInt(new SimpleDateFormat("mm").format(mDate));
		mm = ((int) Math.floor(mm / timeTerm) * timeTerm);
		mTime = new SimpleDateFormat("HH").format(new Date()) + String.format("%1$02d",mm);
	}
	
	public CounterInfoDialog(Context context, String date, String time,
			String place, String memo, OnClickListener listener) throws ParseException {
		mContext = context;
		mDate = sDateFormat.parse(date);
		mTime = time;
		mPlace = place;
		mMemo = memo;
		mListener = listener;
		mPref = PreferenceManager.getDefaultSharedPreferences(context);
	}
	
	/**
	 * ダイアログのキャンセル可否設定
	 * <ul>
	 * <li>TRUE: キャンセル可能</li>
	 * <li>FALSE: キャンセル不可能（デフォルト）</li>
	 * </ul>
	 * 
	 * @param cancel キャンセル可否
	 */
	public void setCancelable(boolean cancel) {
		mCancel = cancel;
	}
	
	/**
	 * ダイアログの表示
	 */
	public void show() {
		// Viewの取得
		final View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_counter_info, null, false);
		
		// 日付ボタン
		Button btnDate = (Button) view.findViewById(R.id.btn_date);
		btnDate.setText(new SimpleDateFormat("MM月dd日").format(mDate));
		btnDate.setOnClickListener(btnDateListener);
		
		// 時間スピナー
		Spinner spnTime = (Spinner) view.findViewById(R.id.spn_time);
		spnTime.setOnItemSelectedListener(spnTimeListener);
		
		int posTime = 0;
		LinkedHashMap<String, Time> mapTime = Common.getTimeList();
		String[] keySet = new String[mapTime.size()];
		mapTime.keySet().toArray(keySet);
		List<Time> listTime = new ArrayList<Time>(mapTime.size());
		for (int i = 0 ; i < mapTime.size() ; i++) {
			Time time = mapTime.get(keySet[i]);
			if (time.getId().equals(mTime)) {
				posTime = i;
			}
			listTime.add(time);
		}
		spnTime.setAdapter(new InfoSpnAdapter<Time>(mContext, listTime));
		spnTime.setSelection(posTime);
		
		
		// 場所スピナー
		Spinner spnPlace = (Spinner) view.findViewById(R.id.spn_place);
		spnPlace.setOnItemSelectedListener(spnPlaceListener);
		
		int posPlace = 0;
		LinkedHashMap<String, Place> mapPlace = Common.getPlaceList();
		keySet = new String[mapPlace.size()];
		mapPlace.keySet().toArray(keySet);
		List<Place> listPlace = new ArrayList<Place>(mapPlace.size());
		for (int i = 0 ; i < mapPlace.size() ; i++) {
			Place place = mapPlace.get(keySet[i]);
			if (place.getId().equals(mPlace)) {
				posPlace = i;
			}
			listPlace.add(place);
		}
		spnPlace.setAdapter(new InfoSpnAdapter<Place>(mContext, listPlace));
		spnPlace.setSelection(posPlace);
		
		// メモ入力欄
		final EditText editMemo = (EditText) view.findViewById(R.id.etext_memo);
		editMemo.setText(mMemo);
		
		// ダイアログ作成
		new AlertDialog.Builder(mContext)
		.setView(view)
		.setCancelable(mCancel)
		.setPositiveButton(R.string.l_ok, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// 場所の保存
				SharedPreferences.Editor prefEditor = mPref.edit();
				prefEditor.putString(PREF_PLACE_ID, mPlace);
				prefEditor.commit();
				
				mListener.onPositiveClick(sDateFormat.format(mDate), mTime, mPlace,
						editMemo.getText().toString().trim());
			}
		})
		.setNegativeButton(R.string.l_cancel, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				mListener.onNegativeClick();
			}
		})
		.create().show();
	}
	
	/**
	 * 日付ボタンのリスナー
	 */
	protected View.OnClickListener btnDateListener = new View.OnClickListener() {
		
		@Override
		public void onClick(final View v) {
			
			Calendar cal = Calendar.getInstance();
			cal.setTime(mDate);
			
			DatePickerDialog dialog = new DatePickerDialog(mContext, new DatePickerDialog.OnDateSetListener() {
				
				@Override
				public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
					Calendar cal = Calendar.getInstance();
					cal.set(year, monthOfYear, dayOfMonth);
					
					mDate = cal.getTime();
					((Button) v).setText(new SimpleDateFormat("MM月dd日").format(mDate));
				}
			}, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
			dialog.show();
			
		}
	};
	
	/**
	 * 時間スピナーのリスナー
	 */
	protected AdapterView.OnItemSelectedListener spnTimeListener = new AdapterView.OnItemSelectedListener() {
		
		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
			Base base = (Base) parent.getItemAtPosition(position);
			mTime = base.getId();
		}
		
		@Override
		public void onNothingSelected(AdapterView<?> parent) {
			// Do nothing
		}
	};
	
	/**
	 * 場所スピナーのリスナー
	 */
	protected AdapterView.OnItemSelectedListener spnPlaceListener = new AdapterView.OnItemSelectedListener() {
		
		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
			Base base = (Base) parent.getItemAtPosition(position);
			mPlace = base.getId();
		}
		
		@Override
		public void onNothingSelected(AdapterView<?> parent) {
			// Do nothing
		}
	};
	
	/**
	 * 時間・場所スピナー共用アダプター
	 * 
	 * @author noxi
	 *
	 */
	protected static class InfoSpnAdapter<T extends Base> extends BaseAdapter {
		
		protected Context mContext;
		protected LayoutInflater mInflater;
		protected List<T> mData;
		
		public InfoSpnAdapter(Context context, List<T> data) {
			mContext = context;
			mData = data;
			mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}
		
		@Override
		public int getCount() {
			return mData.size();
		}
		
		@Override
		public T getItem(int position) {
			return mData.get(position);
		}
		
		@Override
		public long getItemId(int position) {
			return position;
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			return createViewFromResource(position,
					convertView, parent, android.R.layout.simple_spinner_item);
		}
		
		@Override
		public View getDropDownView(int position, View convertView, ViewGroup parent){
			return createViewFromResource(position,
					convertView, parent, android.R.layout.simple_spinner_dropdown_item);
		}
		
		/**
		 * Viewの中身
		 * 
		 * @param position
		 * @param convertView
		 * @param parent
		 * @param resource
		 * @return
		 */
		protected View createViewFromResource(int position,
				View convertView, ViewGroup parent, int resource) {
			
			if (convertView == null) {
				convertView = mInflater.inflate(resource, parent, false);
			}
			TextView text = (TextView) convertView;
			text.setText(mData.get(position).getName());
			
			return convertView;
		}
	}
}
